﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using CLDataAppManagement;
using CLDataAppManagementTS;
using MQTTnet;
using NationalInstruments.TestStand.Interop.API;
using Newtonsoft.Json.Linq;

namespace CLVisionMES
{
    public class MqttMesClientTSCaller
    {
        static IMqttMesClient mQTTCallerInstance = null;

        private static bool CheckInstance(out int ErrorCode, out string ErrorText, out bool Occurred, string methodName)
        {
            if (mQTTCallerInstance == null)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{methodName}: MQTT客户端对象为null！请检查IntMqttClient初始化是否执行成功！";
                Occurred = true;
                return false;
            }
            ErrorCode = 0;
            ErrorText = $"{nameof(MqttMesClientTSCaller)}:{methodName}: Start!";
            Occurred = false;
            return true;
        }

        public static bool IntMqttClient(string server, int port, string username, string password, string topicName, string clientId, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(IntMqttClient)}: Start!";
            Occurred = false;
            try
            {
                mQTTCallerInstance = MqttMesClientFactory.CreateMQTTClient();
                if (mQTTCallerInstance == null)
                {
                    ErrorCode = -1;
                    ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(IntMqttClient)}: 创建MQTT客户端对象失败！请检查dll放置路径是否有误！";
                    Occurred = true;
                    return false;
                }
                bool ret = mQTTCallerInstance.IntMqttClient(server, port, username, password, topicName, clientId, out ErrorCode, out ErrorText);
                if (ErrorCode == -1)
                {
                    Occurred = true;
                    return false;
                }
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(IntMqttClient)}: End!";
                return ret;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(IntMqttClient)}: Fail! " + ex.Message;
                Occurred = true;
                return false;
            }
        }

        public static bool PublishData(string topicName, PropertyObject propertyObject, MQTTnet.Protocol.MqttQualityOfServiceLevel qos, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            if (!CheckInstance(out ErrorCode, out ErrorText, out Occurred, nameof(PublishData)))
                return false;
            try
            {

                JToken jToken = new JObject();
                DataAppManagementTS.Getdata(propertyObject, ref jToken);

                bool ret = mQTTCallerInstance.PublishData(topicName, jToken.ToString(), qos, out ErrorCode, out ErrorText);
                if (ErrorCode == -1)
                {
                    Occurred = true;
                    return false;
                }
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(PublishData)}: End!";
                return ret;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(PublishData)}: Fail! " + ex.Message;
                Occurred = true;
                return false;
            }
        }

        public static bool SubscribeTopic(out int ErrorCode, out string ErrorText, out bool Occurred, params string[] topicNames)
        {
            if (!CheckInstance(out ErrorCode, out ErrorText, out Occurred, nameof(SubscribeTopic)))
                return false;
            try
            {
                bool ret = mQTTCallerInstance.SubscribeTopic(out ErrorCode, out ErrorText, topicNames);
                if (ErrorCode == -1)
                {
                    Occurred = true;
                    return false;
                }
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(SubscribeTopic)}: End!";
                return ret;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(SubscribeTopic)}: Fail! " + ex.Message;
                Occurred = true;
                return false;
            }
        }

        public static bool UnsubscribeTopic(out int ErrorCode, out string ErrorText, out bool Occurred, params string[] topicNames)
        {
            if (!CheckInstance(out ErrorCode, out ErrorText, out Occurred, nameof(UnsubscribeTopic)))
                return false;
            try
            {
                bool ret = mQTTCallerInstance.UnsubscribeTopic(out ErrorCode, out ErrorText, topicNames);
                if (ErrorCode == -1)
                {
                    Occurred = true;
                    return false;
                }
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(UnsubscribeTopic)}: End!";
                return ret;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(UnsubscribeTopic)}: Fail! " + ex.Message;
                Occurred = true;
                return false;
            }
        }

        public static bool DisconnectMqttClient(out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            if (!CheckInstance(out ErrorCode, out ErrorText, out Occurred, nameof(DisconnectMqttClient)))
                return false;
            try
            {
                bool ret = mQTTCallerInstance.DisconnectMqttClient(out ErrorCode, out ErrorText);
                if (ErrorCode == -1)
                {
                    Occurred = true;
                    return false;
                }
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(DisconnectMqttClient)}: End!";
                return ret;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(DisconnectMqttClient)}: Fail! " + ex.Message;
                Occurred = true;
                return false;
            }
        }

        public static bool ReadDataFromFile(PropertyObject propertyObject, string filePath, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            if (!CheckInstance(out ErrorCode, out ErrorText, out Occurred, nameof(ReadDataFromFile)))
                return false;
            try
            {
                JToken jToken = null;
                DataAppManagementTS.LoadFile(filePath, out jToken, out ErrorCode, out ErrorText, out Occurred);

                DataAppManagementTS.AddJTokenToPropertyObject(jToken, ref propertyObject, out ErrorCode, out ErrorText);

                if (ErrorCode == -1)
                {
                    Occurred = true;
                    return false;
                }
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(ReadDataFromFile)}: End!";
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(ReadDataFromFile)}: Fail! " + ex.Message;
                Occurred = true;
                return false;
            }
        }

        public static bool WriteDataToFile(PropertyObject propertyObject, string filePath, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            if (!CheckInstance(out ErrorCode, out ErrorText, out Occurred, nameof(WriteDataToFile)))
                return false;
            try
            {
                JToken jToken = new JObject();
                DataAppManagementTS.Getdata(propertyObject, ref  jToken);
                DataAppManagementTS.SaveFile(filePath, jToken, out ErrorCode, out ErrorText, out Occurred);
             
                if (ErrorCode == -1)
                {
                    Occurred = true;
                    return false;
                }
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(WriteDataToFile)}: End!";
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(WriteDataToFile)}: Fail! " + ex.Message;
                Occurred = true;
                return false;
            }
        }
        public static bool ReceiveDataWithTimeout(out string receivedMessage, out int ErrorCode, out string ErrorText, out bool Occurred, int timeoutMs = 3000, int pollIntervalMs = 50)
        {
            receivedMessage = string.Empty;
            if (!CheckInstance(out ErrorCode, out ErrorText, out Occurred, nameof(ReceiveDataWithTimeout)))
                return false;
            try
            {
                bool ret = mQTTCallerInstance.ReceiveDataWithTimeout(out receivedMessage, out ErrorCode, out ErrorText);
                if (ErrorCode == -1)
                {
                    Occurred = true;
                    return false;
                }
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(ReceiveDataWithTimeout)}: End!";
                return ret;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{nameof(MqttMesClientTSCaller)}:{nameof(ReceiveDataWithTimeout)}: Fail! " + ex.Message;
                Occurred = true;
                return false;
            }
        }
    }
}
